﻿/*
* Copyright (c) 2010-2012 Tesla Engine Group
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


using System;
using SlimDX;
using Tesla.Core;
using Tesla.Graphics;
using Tesla.Math;
using D3D = SlimDX.Direct3D10;
using DXGI = SlimDX.DXGI;

namespace Tesla.Direct3D10.Graphics {
    internal static class D3D10Helper {

        internal static void Convert(ref Color color, out SlimDX.Color4 sdxColor) {
            Tesla.Math.Vector4 v = color.ToVector4();
            sdxColor = new Color4(v.W, v.X, v.Y, v.Z);
        }

        internal static bool SameTargetSize(Texture a, Texture b) {
            int aFormatSize = FormatSize(a.Format);
            int bFormatSize = FormatSize(b.Format);
            int aWidth = 0;
            int aHeight = 0;
            int bWidth = 0;
            int bHeight = 0;
            int aSampleCount = 0;
            int bSampleCount = 0;

            if(a is RenderTarget2D) {
                RenderTarget2D a2d = a as RenderTarget2D;
                aWidth = a2d.Width;
                aHeight = a2d.Height;
                aSampleCount = a2d.MultiSampleCount;
            } else if(a is RenderTargetCube) {
                RenderTargetCube acube = a as RenderTargetCube;
                aWidth = acube.Size;
                aHeight = acube.Size;
                aSampleCount = acube.MultiSampleCount;
            }

            if(b is RenderTarget2D) {
                RenderTarget2D b2d = b as RenderTarget2D;
                bWidth = b2d.Width;
                bHeight = b2d.Height;
                bSampleCount = b2d.MultiSampleCount;
            } else if(b is RenderTargetCube) {
                RenderTargetCube bcube = b as RenderTargetCube;
                bWidth = bcube.Size;
                bHeight = bcube.Size;
                bSampleCount = bcube.MultiSampleCount;
            }

            return (aFormatSize == bFormatSize) && (aWidth == bWidth) && (aHeight == bHeight) && (aSampleCount == bSampleCount);
        }

        internal static void CheckDisposed(D3D.Device device) {
            if(device == null) {
                throw new ArgumentNullException("Graphics device is null.");
            }

            if(device.Disposed) {
                throw new ObjectDisposedException("Underlying device has been disposed.");
            }
        }

        internal static void CheckDisposed(GraphicsResource resource) {
            if(resource == null) {
                throw new ArgumentNullException("Resource is null");
            }

            if(resource.IsDisposed) {
                throw new ObjectDisposedException(resource.GetType().Name);
            }
        }

        internal static void CheckDisposed(Tesla.Graphics.Implementation.GraphicsResourceImplementation resource) {
            if(resource == null) {
                throw new ArgumentNullException("Resource is null");
            }

            if(resource.IsDisposed) {
                throw new ObjectDisposedException(resource.GetType().Name);
            }
        }


        internal static int FormatSize(SurfaceFormat format) {
            switch(format) {
                case SurfaceFormat.Vector4:
                    return 16;
                case SurfaceFormat.Vector3:
                    return 12;
                case SurfaceFormat.Vector2:
                    return 8;
                case SurfaceFormat.Single:
                case SurfaceFormat.Color:
                case SurfaceFormat.RGBA1010102:
                case SurfaceFormat.RG32:
                    return 4;
                case SurfaceFormat.BGR565:
                case SurfaceFormat.BGRA5551:
                    return 2;
                case SurfaceFormat.DXT1:
                case SurfaceFormat.DXT3:
                case SurfaceFormat.DXT5:
                case SurfaceFormat.Alpha8:
                    return 1;
                default:
                    throw new ArgumentException("Invalid format");
            }
        }

        internal static bool IsPowerOfTwo(int num) {
            return ((num & (num-1)) == 0);
        }

        internal static D3D.Filter ToD3DFilter(TextureFilter filter) {
            switch(filter) {
                case TextureFilter.Anisotropic:
                    return D3D.Filter.Anisotropic;
                case TextureFilter.Linear:
                    return D3D.Filter.MinMagMipLinear;
                case TextureFilter.LinearMipPoint:
                    return D3D.Filter.MinMagLinearMipPoint;
                case TextureFilter.Point:
                    return D3D.Filter.MinMagMipPoint;
                case TextureFilter.PointMipLinear:
                    return D3D.Filter.MinMagPointMipLinear;
                case TextureFilter.MinLinearMagPointMipLinear:
                    return D3D.Filter.MinLinearMagPointMipLinear;
                case TextureFilter.MinLinearMagPointMipPoint:
                    return D3D.Filter.MinLinearMagMipPoint;
                case TextureFilter.MinPointMagLinearMipLinear:
                    return D3D.Filter.MinPointMagMipLinear;
                case TextureFilter.MinPointMagLinearMipPoint:
                    return D3D.Filter.MinPointMagLinearMipPoint;
                default:
                    throw new ArgumentException("Invalid filter");
            }
        }

        internal static D3D.TextureAddressMode ToD3DTextureAddressMode(TextureAddressMode mode) {
            switch(mode) {
                case TextureAddressMode.Clamp:
                    return D3D.TextureAddressMode.Clamp;
                case TextureAddressMode.Mirror:
                    return D3D.TextureAddressMode.Mirror;
                case TextureAddressMode.Wrap:
                    return D3D.TextureAddressMode.Wrap;
                default:
                    throw new ArgumentException("Invalid address mode");
            }
        }

        internal static D3D.StencilOperation ToD3DStencilOperation(StencilOperation func) {
            switch(func) {
                case StencilOperation.Zero:
                    return D3D.StencilOperation.Zero;
                case StencilOperation.Replace:
                    return D3D.StencilOperation.Replace;
                case StencilOperation.Keep:
                    return D3D.StencilOperation.Keep;
                case StencilOperation.Invert:
                    return D3D.StencilOperation.Invert;
                case StencilOperation.IncrementAndClamp:
                    return D3D.StencilOperation.IncrementAndClamp;
                case StencilOperation.Increment:
                    return D3D.StencilOperation.Increment;
                case StencilOperation.DecrementAndClamp:
                    return D3D.StencilOperation.DecrementAndClamp;
                case StencilOperation.Decrement:
                    return D3D.StencilOperation.Decrement;
                default:
                    throw new ArgumentException("Invalid stencil function");
            }
        }

        internal static D3D.Comparison ToD3DComparison(ComparisonFunction func) {
            switch(func) {
                case ComparisonFunction.Always:
                    return D3D.Comparison.Always;
                case ComparisonFunction.Equal:
                    return D3D.Comparison.Equal;
                case ComparisonFunction.Greater:
                    return D3D.Comparison.Greater;
                case ComparisonFunction.GreaterEqual:
                    return D3D.Comparison.GreaterEqual;
                case ComparisonFunction.Less:
                    return D3D.Comparison.Less;
                case ComparisonFunction.LessEqual:
                    return D3D.Comparison.LessEqual;
                case ComparisonFunction.Never:
                    return D3D.Comparison.Never;
                case ComparisonFunction.NotEqual:
                    return D3D.Comparison.NotEqual;
                default:
                    throw new ArgumentException("Invalid compare function");
            }
        }

        internal static D3D.BlendOperation ToD3DBlendOperation(BlendFunction func) {
            switch(func) {
                case BlendFunction.Add:
                    return D3D.BlendOperation.Add;
                case BlendFunction.Max:
                    return D3D.BlendOperation.Maximum;
                case BlendFunction.Min:
                    return D3D.BlendOperation.Minimum;
                case BlendFunction.ReverseSubtract:
                    return D3D.BlendOperation.ReverseSubtract;
                case BlendFunction.Subtract:
                    return D3D.BlendOperation.Subtract;
                default:
                    throw new ArgumentException("Invalid blend function");
            }
        }

        internal static D3D.BlendOption ToD3DBlendOption(Blend blend) {
            switch(blend) {
                case Blend.Zero:
                    return D3D.BlendOption.Zero;
                case Blend.SourceColor:
                    return D3D.BlendOption.SourceColor;
                case Blend.SourceAlphaSaturation:
                    return D3D.BlendOption.SourceAlphaSaturate;
                case Blend.SourceAlpha:
                    return D3D.BlendOption.SourceAlpha;
                case Blend.One:
                    return D3D.BlendOption.One;
                case Blend.InverseSourceColor:
                    return D3D.BlendOption.InverseSourceColor;
                case Blend.InverseSourceAlpha:
                    return D3D.BlendOption.InverseSourceAlpha;
                case Blend.InverseDestinationColor:
                    return D3D.BlendOption.InverseDestinationColor;
                case Blend.InverseDestinationAlpha:
                    return D3D.BlendOption.InverseDestinationAlpha;
                case Blend.InverseBlendFactor:
                    return D3D.BlendOption.InverseBlendFactor;
                case Blend.DestinationColor:
                    return D3D.BlendOption.DestinationColor;
                case Blend.DestinationAlpha:
                    return D3D.BlendOption.DestinationAlpha;
                case Blend.BlendFactor:
                    return D3D.BlendOption.BlendFactor;
                default:
                    throw new ArgumentException("Invalid blend mode");
            }
        }

        internal static D3D.CullMode ToD3DCullMode(CullMode cull) {
            switch(cull) {
                case CullMode.Back:
                    return D3D.CullMode.Back;
                case CullMode.Front:
                    return D3D.CullMode.Front;
                case CullMode.None:
                    return D3D.CullMode.None;
                default:
                    throw new ArgumentException("Invalid cull mode");
            }
        }

        internal static D3D.FillMode ToD3DFillMode(FillMode fill) {
            switch(fill) {
                case FillMode.Solid:
                    return D3D.FillMode.Solid;
                case FillMode.WireFrame:
                    return D3D.FillMode.Wireframe;
                default:
                    throw new ArgumentException("Invalid fill mode");
            }
        }

        internal static Exception GetExceptionFromResult(Result r){
            switch(r.Code) {
                case -2005529772:
                    return new InvalidOperationException("Cannot modify index buffer.");
                case -2005529764:
                    return new InvalidOperationException("Cannot remove last item.");
                case -2005529770:
                    return new InvalidOperationException("Cannot sort by attribute.");
                case -2005336062:
                    return new InvalidOperationException("File not found.");
                case -2005529765:
                    return new TeslaException("Duplicate named fragment.");
                case -2147467259:
                    return new TeslaException("General failure.");
                case -2147024809:
                    return new ArgumentException("Invalid argument");
                case -2005530516:
                    return new InvalidOperationException("Invalid call.");
                case -2005529767:
                    return new TeslaException("Invalid data.");
                case -2005529771:
                    return new TeslaException("Invalid mesh.");
                case -2005529766:
                    return new TeslaException("Loaded mesh has no data.");
                case -2005529769:
                    return new NotSupportedException("Skinning not supported.");
                case -2005529768:
                    return new TeslaException("Too many influences.");
                case -2005336063:
                    return new TeslaException("Too many unique state objects.");
                case -2005532132:
                    return new InvalidOperationException("Was still drawing.");
                case -2147024882:
                    return new OutOfMemoryException("Out of memory.");
                default:
                    return null;
            }
        }

        internal static void CheckArrayBounds(Array data, int index, int count) {
            if(data == null || data.Length == 0) {
                throw new ArgumentNullException("data", "Array data is null");
            }
            if(count <= 0) {
                throw new ArgumentOutOfRangeException("count", "Count must be greater than zero.");
            }
            if(index < 0) {
                throw new ArgumentOutOfRangeException("index", "Offset is out of range.");
            }
            if(index + count > data.Length) {
                throw new ArgumentOutOfRangeException("Count and offset must be less than the array length.");
            }
        }

        internal static SurfaceFormat FromD3DSurfaceFormat(DXGI.Format f) {
            switch(f) {
                case DXGI.Format.R8G8B8A8_UNorm:
                    return SurfaceFormat.Color;
                case DXGI.Format.B5G5R5A1_UNorm:
                    return SurfaceFormat.BGRA5551;
                case DXGI.Format.B5G6R5_UNorm:
                    return SurfaceFormat.BGR565;
                case DXGI.Format.R32_Float:
                    return SurfaceFormat.Single;
                case DXGI.Format.R32G32_Float:
                    return SurfaceFormat.Vector2;
                case DXGI.Format.R32G32B32_Float:
                    return SurfaceFormat.Vector3;
                case DXGI.Format.R32G32B32A32_Float:
                    return SurfaceFormat.Vector4;
                case DXGI.Format.A8_UNorm:
                    return SurfaceFormat.Alpha8;
                case DXGI.Format.R16G16_UNorm:
                    return SurfaceFormat.RG32;
                case DXGI.Format.R10G10B10A2_UNorm:
                    return SurfaceFormat.RGBA1010102;
                case DXGI.Format.R16G16B16A16_UNorm:
                    return SurfaceFormat.RGBA64;
                case DXGI.Format.BC1_UNorm:
                    return SurfaceFormat.DXT1;
                case DXGI.Format.BC2_UNorm:
                    return SurfaceFormat.DXT3;
                case DXGI.Format.BC3_UNorm:
                    return SurfaceFormat.DXT5;
                default :
                    throw new ArgumentException("Invalid DXGI format, cannot convert to engine Tesla SurfaceFormat");
            }
        }

        internal static DXGI.Format ToD3DSurfaceFormat(SurfaceFormat f) {
            switch(f) {
                case SurfaceFormat.Color:
                    return DXGI.Format.R8G8B8A8_UNorm;
                case SurfaceFormat.BGRA5551:
                    return DXGI.Format.B5G5R5A1_UNorm;
                case SurfaceFormat.BGR565:
                    return DXGI.Format.B5G6R5_UNorm;
                case SurfaceFormat.Single:
                    return DXGI.Format.R32_Float;
                case SurfaceFormat.Vector2:
                    return DXGI.Format.R32G32_Float;
                case SurfaceFormat.Vector3:
                    return DXGI.Format.R32G32B32_Float;
                case SurfaceFormat.Vector4:
                    return DXGI.Format.R32G32B32A32_Float;
                case SurfaceFormat.Alpha8:
                    return DXGI.Format.A8_UNorm;
                case SurfaceFormat.RG32:
                    return DXGI.Format.R16G16_UNorm;
                case SurfaceFormat.RGBA1010102:
                    return DXGI.Format.R10G10B10A2_UNorm;
                case SurfaceFormat.RGBA64:
                    return DXGI.Format.R16G16B16A16_UNorm;
                case SurfaceFormat.DXT1:
                    return DXGI.Format.BC1_UNorm;
                case SurfaceFormat.DXT3:
                    return DXGI.Format.BC2_UNorm;
                case SurfaceFormat.DXT5:
                    return DXGI.Format.BC3_UNorm;
                default:
                    throw new ArgumentException("Invalid Tesla SurfaceFormat, cannot convert to DXGI format");
            }
        }

        internal static DepthFormat FromD3DDepthFormat(DXGI.Format f) {
            switch(f) {
                case DXGI.Format.D32_Float:
                    return DepthFormat.Depth32;
                case DXGI.Format.D32_Float_S8X24_UInt:
                    return DepthFormat.Depth24;
                case DXGI.Format.D24_UNorm_S8_UInt:
                    return DepthFormat.Depth24Stencil8;
                case DXGI.Format.D16_UNorm:
                    return DepthFormat.Depth16;
                default:
                    throw new ArgumentException("Invalid DXGI depth format, cannot convert to Tesla DepthFormat");
            }
        }

        internal static DXGI.Format ToD3DDepthFormat(DepthFormat f) {
            switch(f) {
                case DepthFormat.Depth32:
                    return DXGI.Format.D32_Float;
                case DepthFormat.Depth24:
                    return DXGI.Format.D32_Float_S8X24_UInt;
                case DepthFormat.Depth24Stencil8:
                    return DXGI.Format.D24_UNorm_S8_UInt;
                case DepthFormat.Depth16:
                    return DXGI.Format.D16_UNorm;
                default:
                    throw new ArgumentException("Invalid Tesla DepthFormat, cannot convert to DXGI format");
            }
        }

        internal static DXGI.Format ToD3DVertexFormat(VertexFormat format) {
            switch(format) {
                case VertexFormat.Single:
                    return DXGI.Format.R32_Float;
                case VertexFormat.Vector2:
                    return DXGI.Format.R32G32_Float;
                case VertexFormat.Vector3:
                    return DXGI.Format.R32G32B32_Float;
                case VertexFormat.Vector4:
                    return DXGI.Format.R32G32B32A32_Float;
                case VertexFormat.Color:
                    return DXGI.Format.R8G8B8A8_UNorm;
                default:
                    throw new ArgumentException("Invalid Tesla VertexElementFormat, cannot convert to DXGI format");
            }
        }

        internal static D3D.DepthStencilViewDimension ToD3DDepthStencilViewDimension(TextureDimensions dimensions, bool multisampleEnabled) {
            switch(dimensions) {
                case TextureDimensions.One:
                    return D3D.DepthStencilViewDimension.Texture1DArray;
                case TextureDimensions.Two:
                    if(multisampleEnabled) {
                        return D3D.DepthStencilViewDimension.Texture2DMultisampled;
                    } else {
                        return D3D.DepthStencilViewDimension.Texture2D;
                    }
                case TextureDimensions.Cube:
                    if(multisampleEnabled) {
                        return D3D.DepthStencilViewDimension.Texture2DMultisampledArray;
                    } else {
                        return D3D.DepthStencilViewDimension.Texture2DArray;
                    }
                case TextureDimensions.Three:
                default:
                    throw new ArgumentException("Invalid dimensions for depth buffer creation");
            }
        }

        internal static D3D.RenderTargetViewDimension ToD3DRenderTargetViewDimension(TextureDimensions dimensions, bool multisampleEnabled) {
            switch(dimensions) {
                case TextureDimensions.One:
                    return D3D.RenderTargetViewDimension.Texture1DArray;
                case TextureDimensions.Two:
                    if(multisampleEnabled) {
                        return D3D.RenderTargetViewDimension.Texture2DMultisampled;
                    } else {
                        return D3D.RenderTargetViewDimension.Texture2D;
                    }
                case TextureDimensions.Three:
                    return D3D.RenderTargetViewDimension.Texture3D;
                case TextureDimensions.Cube:
                    if(multisampleEnabled) {
                        return D3D.RenderTargetViewDimension.Texture2DMultisampledArray;
                    } else {
                        return D3D.RenderTargetViewDimension.Texture2DArray;
                    }
                default:
                    throw new ArgumentException("Invalid dimensions for render target creation");
            }
        }

        internal static D3D.InputClassification ToD3DInputClassification(int i) {
            if(i == 1) {
                return D3D.InputClassification.PerInstanceData;
            } else {
                return D3D.InputClassification.PerVertexData;
            }
        }

        internal static D3D.InputElement[] ToD3DInputElements(VertexElement[] elements) {
            D3D.InputElement[] inputs = new D3D.InputElement[elements.Length];
            for(int i = 0; i < elements.Length; i++) {
                VertexElement element = elements[i];
                inputs[i] = new D3D.InputElement(ToD3DVertexSemantic(element.SemanticName),
                    element.SemanticIndex,
                    D3D10Helper.ToD3DVertexFormat(element.Format),
                    element.Offset,
                    0,
                    0,
                    0);
            }
            return inputs;
        }

        internal static D3D.Viewport ToD3DViewport(Viewport vp) {
            D3D.Viewport d3dvp = new SlimDX.Direct3D10.Viewport();
            d3dvp.Height = vp.Height;
            d3dvp.Width = vp.Width;
            d3dvp.MaxZ = vp.MaxDepth;
            d3dvp.MinZ = vp.MinDepth;
            d3dvp.X = vp.X;
            d3dvp.Y = vp.Y;
            return d3dvp;
        }

        internal static D3D.PrimitiveTopology ToD3DPrimitiveType(PrimitiveType primType) {
            switch(primType) {
                case PrimitiveType.LineList:
                    return D3D.PrimitiveTopology.LineList;
                case PrimitiveType.LineStrip:
                    return D3D.PrimitiveTopology.LineStrip;
                case PrimitiveType.TriangleStrip:
                    return D3D.PrimitiveTopology.TriangleStrip;
                case PrimitiveType.TriangleList:
                    return D3D.PrimitiveTopology.TriangleList;
                default:
                    throw new ArgumentException("Invalid Tesla PrimitiveType, cannot convert to D3D10 PrimitiveTopology");
            }
        }

        internal static PrimitiveType FromD3DPrimitiveType(D3D.PrimitiveTopology top) {
            switch(top) {
                case D3D.PrimitiveTopology.TriangleList:
                    return PrimitiveType.TriangleList;
                case D3D.PrimitiveTopology.LineList:
                    return PrimitiveType.LineList;
                case D3D.PrimitiveTopology.TriangleStrip:
                    return PrimitiveType.TriangleStrip;
                case D3D.PrimitiveTopology.LineStrip:
                    return PrimitiveType.LineStrip;
                default:
                    throw new ArgumentException("Invalid D3D10 PrimitiveTopology, cannot convert to Tesla PrimitiveType");
            }
        }

        internal static bool IsFlagSet(int flag, int mask) {
            return ((flag & mask) == mask) ? true : false;
        }

        internal static String ToD3DVertexSemantic(VertexSemantic semantic) {
            switch(semantic) {
                case VertexSemantic.Position:
                    return "POSITION";
                case VertexSemantic.Normal:
                    return "NORMAL";
                case VertexSemantic.Color:
                    return "COLOR";
                case VertexSemantic.TextureCoordinate:
                    return "TEXCOORD";
                case VertexSemantic.Binormal:
                    return "BINORMAL";
                case VertexSemantic.Tangent:
                    return "TANGENT";
                case VertexSemantic.BlendIndices:
                    return "BLENDINDICES";
                case VertexSemantic.BlendWeight:
                    return "BLENDWEIGHT";
                case VertexSemantic.Depth:
                    return "DEPTH";
                case VertexSemantic.Fog:
                    return "FOG";
                case VertexSemantic.PointSize:
                    return "PSIZE";
                default:
                    throw new ArgumentException("Invalid vertex semantic");
            }
        }

        internal static VertexSemantic FromD3DVertexSemantic(String s) {
            switch(s) {
                case "POSITION":
                    return VertexSemantic.Position;
                case "NORMAL":
                    return VertexSemantic.Normal;
                case "COLOR":
                    return VertexSemantic.Color;
                case "TEXCOORD":
                    return VertexSemantic.TextureCoordinate;
                case "BINORMAL":
                    return VertexSemantic.Binormal;
                case "TANGENT":
                    return VertexSemantic.Tangent;
                case "BLENDINDICES":
                    return VertexSemantic.BlendIndices;
                case "BLENDWEIGHT":
                    return VertexSemantic.BlendWeight;
                case "DEPTH":
                    return VertexSemantic.Depth;
                case "FOG":
                    return VertexSemantic.Fog;
                case "PSIZE":
                    return VertexSemantic.PointSize;
                default:
                    throw new ArgumentException("Invalid vertex semantic");
            }
        }

        /*
        public static InputLayout MergeDeclarations(SlimDX.Direct3D10.Device device, ShaderSignature sig, VertexDeclaration decl1, VertexDeclaration decl2) {
            InputElement[] elems = new InputElement[decl1.VertexElements.Length + decl2.VertexElements.Length];

            int index = 0;
            for(int i = 0; i < decl1.VertexElements.Length; i++) {
                VertexElement e = decl1.VertexElements[i];
                elems[i] = new InputElement(Constants.Semantics[(int) e.SemanticName],
                    e.SemanticIndex,
                    D3D10Helper.ToD3DVertexFormat(e.Format),
                    e.Offset,
                    0,
                    0,
                    0);
                index++;
            }

            for(int i = 0; i < decl2.VertexElements.Length; i++) {
                VertexElement e = decl2.VertexElements[i];
                elems[index] = new InputElement(Constants.Semantics[(int) e.SemanticName],
                    e.SemanticIndex,
                    D3D10Helper.ToD3DVertexFormat(e.Format),
                    e.Offset,
                    1,
                    0,
                    0);
                index++;
            }

            return new InputLayout(device, sig, elems);
        }*/
    }
}
